<?php defined('SYSPATH') or die('No direct script access.');
/**
 * 会员认证封装
 *
 * @author  Yellow.Chow <aultoale@gmail.com>
 * @version $Id: auth.php 1 2014-01-13 15:05:51Z zhouyl $
 * @license http://www.gnu.org/licenses/gpl-3.0.html    GPL 3
 */
class Auth
{

    /**
     * 登录失败次数限制
     *
     * @var int
     */
    public static $failed_limit = 5;

    /**
     * 失败限制锁定时间 (秒)
     *
     * @var int
     */
    public static $failed_seconds = 300;

    /**
     * 存储在 cookie 中的 token id
     *
     * @var string
     */
    public static $cookie_token = 'authtoken';

    /**
     * 会员认证类单件实例
     *
     * @var Auth
     */
    protected static $_instance = NULL;

    /**
     * Session 存储
     *
     * @var Session_NameSpace
     */
    protected $_session = NULL;

    /**
     * Auth_Db 数据库实例
     *
     * @var Auth_Db
     */
    protected $_db = NULL;

    /**
     * 单件模式调用
     *
     * @return Auth
     */
    public static function instance()
    {
        if (self::$_instance === NULL)
        {
            self::$_instance = new self();
        }

        return self::$_instance;
    }

    /**
     * 构造方法
     */
    protected function __construct()
    {
        $this->_db = new Auth_Db();
        $this->_session = Session_NameSpace::factory(__CLASS__);
    }

    /**
     * 禁止使用 clone 方法
     */
    final protected function __clone()
    {}

    /**
     * 会员登录
     *
     * @param  string  $account   邮箱/昵称
     * @param  string  $password  登录密码(未加密)
     * @param  int     $lifetime  保存密码的周期
     */
    public function login($account, $password, $lifetime = FALSE)
    {
        $result = $this->_db->login($account, $password, $lifetime);

        // 完成登录信息
        $this->_comple_login($result);
    }

    /**
     * 返回登录验证失败次数
     *
     * @param  int  $nums  设置为 0 时重置失败次数
     * @return int
     */
    public function failures($nums = NULL)
    {
        return $this->_db->failures($nums);
    }

    /**
     * 完成登录信息
     *
     * @param  stdClass  $result
     */
    protected function _comple_login(stdClass $result)
    {
        $this->_session->set(array(
            'logined'   => TRUE,
            'member_id' => (int) $result->member_id,
            'email'     => $result->email,
            'nickname'  => $result->nickname,
            'last_ip'   => $result->last_ip,
            'last_time' => $result->last_time,
            'realname'  => $result->realname,
            'mobile'    => $result->mobile,
            'region_id' => (int) $result->region_id,
            'address'   => $result->address,
            'avatar'    => $result->avatar,
        ));
    }

    /**
     * 刷新 SESSION 数据
     */
    public function refresh()
    {
        if ($this->is_logined())
        {
            $result = $this->_db->member_sql()
                ->where('mem.member_id', '=', $this->_session->member_id)
                ->where('mem.email', '=', $this->_session->email)
                ->fetch_row();

            $this->_comple_login($result);
        }
    }

    /**
     * 退出登录
     *
     * @return Auth
     */
    public function logout()
    {
        Cookie::delete(Auth::$cookie_token);

        $this->_session->clean();
    }

    /**
     * 判断是否登录
     *
     * @return bool
     */
    public function is_logined()
    {
        if ($this->_session->logined !== TRUE) // 未登录
        {
            $token = Cookie::get(Auth::$cookie_token); // 自动登录
            if (empty($token))
            {
                return FALSE;
            }
            $result = $this->_db->auto_login($token);

            if ( ! $result instanceof stdClass)
            {
                return FALSE;
            }

            // 完成登录信息
            $this->_comple_login($result);
        }

        if ($this->_session->last_ip != Request::$client_ip OR $this->_session->last_time < strtotime('-1 day'))
        {
            $data = array(
                'last_ip' => Request::$client_ip,
                'last_time' => time(),
            );
            $this->_db->update($data, $this->_session->member_id);

            $this->_db->update_logins($this->_session->member_id);

            $this->_session->set($data);
        }

        return TRUE;
    }

    /**
     * 获取已经存储的用户信息
     *
     * @param  string  $key
     * @return string
     */
    public function __get($key)
    {
        return $this->_session->get($key);
    }

    /**
     * 获取所有的用户信息
     *
     * @return array
     */
    public function as_array()
    {
        return $this->_session->as_array();
    }

}